﻿using Eps.Ai.Common;
using HalconDotNet;
using InfonavaEye.model.wjapi;
using InfonavaEye.util;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using static InfonavaEye.util.ZipHelper;

namespace InfonavaEye.Forms
{
    public partial class UpgradeForm : Form
    {

        private string _downfilename = "";

        private Upgrade _upgradeData;
        public void upgradeData(Upgrade upgrade)
        {
            this._upgradeData = upgrade;
            //this._upgradeData.wgtUrl = "http://192.168.0.130/infonavaEyeV050517.zip";
        }
        public UpgradeForm()
        {
            InitializeComponent();
        }

        private void FormLoad(object sender, EventArgs e)
        {
            this.currentVersion.Text = Config.APP_VERSION;
            this.laseVersion.Text = _upgradeData.version;
            //this.mergeConfigFile(@"D:\\data\\iniFileTest\\config.ini", @"D:\\data\\iniFileTest\\configV3.ini");
           this.downloadUpgraderFile();
         // ZipHelper.Compress("D:\\projectCode\\infynova-eye-desk\\InfonavaEye\\bin\\x64\\infonavaEye", "D:\\data\\appUpgrde", "infonavaEyeV050517.zip");
        }

        /// <summary>
        /// 下载升级压缩包
        /// </summary>
        private void downloadUpgraderFile()
        {
            string upgradeDir = tmpUpgradeDir();
            WebClient webClient = new WebClient();
            if (webClient.IsBusy)
            {
                webClient.CancelAsync();
            }
            string fileUrl = _upgradeData.wgtUrl;
            _downfilename = fileUrl.Substring(fileUrl.LastIndexOf("/") + 1, fileUrl.Length - (fileUrl.LastIndexOf("/") + 1));
            upgradeDir = upgradeDir + "\\" + _downfilename;
            webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged);
            webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted);
            webClient.DownloadFileAsync(new Uri(_upgradeData.wgtUrl), upgradeDir);
        }

        private string tmpUpgradeDir() {
            DirectoryInfo currentDir = new DirectoryInfo(Directory.GetCurrentDirectory());
            DirectoryInfo tmpUpgradeDirParent = currentDir.Parent;
            string upgradeDir = tmpUpgradeDirParent.FullName + "\\" + _upgradeData.appId + "-" + _upgradeData.version;
            if (!Directory.Exists(upgradeDir))
            {
                Directory.CreateDirectory(upgradeDir);
            }
            return upgradeDir;
        }
        /// <summary>
        /// 下载进度条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
            this.progressLab.Text = "" + e.ProgressPercentage;
        }

        /// <summary>
        /// 下载完成后的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                this.progressLab.Text = "下载被取消!";
            }
            else
            {
                this.progressLab.Text = "下载完成!";
                try
                {
                    Thread.Sleep(1000);
                    //开始解压
                   string upgradeDir = this.tmpUpgradeDir();
                    string decomDir = _downfilename.Substring(0, _downfilename.LastIndexOf("."));
                    decomDir = upgradeDir + "\\" + decomDir;
                    if (!Directory.Exists(decomDir)) {
                        Directory.CreateDirectory(decomDir);
                    }
                    this.progressLab.Text = "正在更新程序，请勿关闭....";
                    GZipResult decompRessResult = ZipHelper.Decompress(upgradeDir, decomDir, _downfilename);
                    if (decompRessResult.Errors == false) {
                        DirectoryInfo currentDir = new DirectoryInfo(Directory.GetCurrentDirectory());
                        bool mergeResult= mergeConfigFile(currentDir.FullName + "\\config.ini", decomDir + "\\config.ini");
                        if (mergeResult)
                        {
                          //  File.Copy(currentDir.FullName + "\\config.ini", decomDir + "\\config.ini");
                            this.voidAutoUpdateCmd(currentDir.FullName + "\\AutoUpdate.bat", decomDir, currentDir.FullName);
                          //  DirectoryInfo source = new DirectoryInfo(decomDir);
                          //  CopyTo(source, currentDir.FullName, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    progressBar1.Visible = false;
                    progressLab.Text = ex.Message;
                }
            }
        }

        private bool mergeConfigFile(string oldIniConfigFile, string newIniConfigFile)
        {
            List<string> oldSectionList = IniFileUtils.ReadSections(oldIniConfigFile);
            List<string> newSectionList = IniFileUtils.ReadSections(newIniConfigFile);

            Dictionary<string, string> oldkeys = new Dictionary<string, string>();
            Dictionary<string, string> newkeys = new Dictionary<string, string>();
            bool mergeResult= false;
            foreach (string section in oldSectionList)
            {
                List<string> keys = IniFileUtils.ReadKeys(section, oldIniConfigFile);
                if (keys.Count > 0)
                {
                    foreach (string key in keys)
                    {
                        oldkeys.Add(section + "&" + key, key);
                    }
                }
            }
            foreach (string section in newSectionList)
            {
                List<string> keys = IniFileUtils.ReadKeys(section, newIniConfigFile);
                if (keys.Count > 0)
                {
                    foreach (string key in keys)
                    {
                        newkeys.Add(section + "&" + key, key);
                    }
                }
            }
            Dictionary<string, string> addList = new Dictionary<string, string>();
            if (newkeys.Count > 0)
            {
                foreach (string key in newkeys.Keys)
                {
                    if (!oldkeys.ContainsKey(key))
                    {
                        var keySlip = key.Split("&".ToCharArray());
                        var value = IniFileUtils.ReadIniData(keySlip[0], keySlip[1], null, newIniConfigFile);
                        IniFileUtils.WriteIniData(keySlip[0], keySlip[1], value, oldIniConfigFile);
                        mergeResult = true;
                    }
                }
            }
            //更新版本号
            IniFileUtils.WriteIniData("device", "APP_VERSION", "V"+_upgradeData.version, oldIniConfigFile);
            return mergeResult;
        }

        private  void CopyTo(DirectoryInfo source,
            string destDirectory, bool recursive)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (destDirectory == null)
                throw new ArgumentNullException("destDirectory");
            if (!source.Exists)
                throw new DirectoryNotFoundException(
                       "Source directory not found:" + source.FullName);
            DirectoryInfo target = new DirectoryInfo(destDirectory);
            if (!target.Exists)
                target.Create();
            foreach (FileInfo file in source.GetFiles())
            {
                file.CopyTo(Path.Combine(target.FullName, file.Name), true);
            }
            if (!recursive)
                return;
            foreach (DirectoryInfo directory in source.GetDirectories())
            {
                CopyTo(directory,
                    Path.Combine(target.FullName, directory.Name), recursive);
            }
            this.progressLab.Text = "更新完成，请重启软件.....";
        }

        private void voidAutoUpdateCmd(String batFile,String sourceDirectory, string destDirectory) {
            Process proc = new Process();
            Process currentProcess= Process.GetCurrentProcess();
            proc.StartInfo.FileName = batFile;
            proc.StartInfo.Arguments = sourceDirectory + " "+ destDirectory+" "+ currentProcess.Id;
            proc.StartInfo.UseShellExecute = true;
            proc.StartInfo.CreateNoWindow= false;
            proc.StartInfo.Verb = "runas";
            proc.Start();
            proc.WaitForExit();
          //  System.Diagnostics.Process.GetCurrentProcess().Kill();
        }
    }
}
